import sys
import tempfile
import ttkbootstrap as tk

from ttkbootstrap.constants import *
from ttkbootstrap.dialogs import Dialog
from ttkbootstrap.localization import MessageCatalog
from ttkbootstrap.utility import enable_high_dpi_awareness
from pathlib import Path
from PIL import Image, ImageTk

from src.log import HOMEP
from src.draw import drawMessageBoxImage
from src.common import FONT_FILE_NAME, FONT_FAMILY, shutdown


class MessageBox(Dialog):
    
    def __init__(self, parent):
        self.__parent = parent
        self._padding = (20, 20)
        self._title = ''
        self._icon = None
        self._message = None
        self._cancel_text = None
        self._ok_text = None
        self._buttons = None
    
    def initUI(self, params):
        super().__init__(self.__parent, params.title, False)
        self._title = params.title

        # 根据类型选择不同的图片
        if params.type == 'info':
            self._icon = str(HOMEP.joinpath('rawfile', 'icon_info.png'))
        elif params.type == 'success':
            self._icon = str(HOMEP.joinpath('rawfile', 'icon_success.png'))
        elif params.type == 'warning':
            self._icon = str(HOMEP.joinpath('rawfile', 'icon_warning.png'))
        elif params.type == 'error':
            self._icon = str(HOMEP.joinpath('rawfile', 'icon_error.png'))
        elif params.type == 'question':
            self._icon = str(HOMEP.joinpath('rawfile', 'icon_question.png'))
        elif params.type == 'delete':
            self._icon = str(HOMEP.joinpath('rawfile', 'icon_delete.png'))
        else:
            self._icon = None
        
        self._message = params.content

        if not params.hideCancel:
            self._cancel_text = params.cancelText
            self._ok_text = params.okText
            self._buttons = [
                f"{MessageCatalog.translate(params.cancelText)}:secondary",
                f"{MessageCatalog.translate(params.okText)}:primary"
            ]
        else:
            self._cancel_text = None
            self._ok_text = params.okText
            self._buttons = [
                f"{MessageCatalog.translate(params.okText)}:primary"
            ]
    
    def create_body(self, master):
        """Overrides the parent method; adds the message section."""
        container = tk.Frame(master)

        font_path = str(HOMEP.joinpath('rawfile', FONT_FILE_NAME))
        with tempfile.TemporaryDirectory() as temp_dir:
            temp_img = Path(temp_dir) / 'messagebox.png'
            # 绘制图像
            if str(self._icon).endswith('icon_delete.png'):
                has_image = drawMessageBoxImage(font_path, ['#F56C6C'], self._title, self._icon, self._message, str(temp_img))
            else:
                has_image = drawMessageBoxImage(font_path, ['#409EFF', '#F56C6C'], self._title, self._icon, self._message, str(temp_img))

            if has_image:
                original_image = Image.open(temp_img)

                # Pillow 图像转换为 Tkinter 可用的格式
                tk_image = ImageTk.PhotoImage(original_image)

                # 创建并配置 Label 组件来显示图片
                image_label = tk.Label(container, image=tk_image)
                # 设置 Label 组件的背景颜色为透明
                # image_label.config(background=self.transparent_color)
                image_label.image = tk_image
                image_label.pack(fill=X, anchor=N)

        container.pack(fill=X, expand=True)
        return container

    def create_buttonbox(self, master):
        """Overrides the parent method; adds the message buttonbox"""
        frame = tk.Frame(master)

        button_list = []

        style = tk.Style()
        style.configure('primary.TButton', foreground='#ffffff', background='#4080ff', borderwidth=0, font=(FONT_FAMILY, 12))
        style.configure('danger.TButton', foreground='#ffffff', background='#F56C6C', borderwidth=0, font=(FONT_FAMILY, 12))
        style.configure('secondary.TButton', foreground='#606266', background='#e4e7ed', borderwidth=0, font=(FONT_FAMILY, 12))

        for i, button in enumerate(self._buttons[::-1]):
            cnf = button.split(":")
            if len(cnf) == 2:
                text, bootstyle = cnf

                if str(self._icon).endswith('icon_delete.png') and bootstyle == "primary":
                    bootstyle = "danger"
            else:
                text = cnf[0]
                bootstyle = "secondary"

            # if self._localize == True:
            #     text = MessageCatalog.translate(text)

            btn = tk.Button(frame, bootstyle=bootstyle, text=text)
            btn.configure(command=lambda b=btn: self.on_button_press(b))
            btn.config(padding=(18, 6, 18, 10))

            btn.pack(padx=10, side=RIGHT)
            btn.lower()  # set focus traversal left-to-right
            button_list.append(btn)

        # tk.Separator(self._toplevel).pack(fill=X)
        # 放置在底部12px离右侧12px
        frame.place(relx=1.0, rely=1.0, anchor=SE, x=-16, y=-24)

    def on_button_press(self, button):
        """Save result, destroy the toplevel, and execute command."""
        self._result = button["text"]
        self._toplevel.destroy()
        if self._result == self._ok_text:
            sys.stdout.write('用户点击了确定\n')
            sys.stdout.flush()
            shutdown()
        else:
            sys.stdout.write('用户点击了取消\n')
            sys.stdout.flush()
            shutdown()

    def build(self):
        """Build the dialog from settings"""

        # setup toplevel based on widowing system
        if self._winsys == "win32":
            self._toplevel = tk.Toplevel(
                transient=self.master,
                title=self._title,
                resizable=(0, 0),
                minsize=(300, 15),
                iconify=True,
                overrideredirect=True,
            )
        else:
            self._toplevel = tk.Toplevel(
                transient=self.master,
                title=self._title,
                resizable=(0, 0),
                windowtype="dialog",
                iconify=True,
                overrideredirect=True,
            )

        self._toplevel.withdraw()  # reset the iconify state

        # bind <Escape> event to window close
        self._toplevel.bind("<Escape>", lambda _: self._toplevel.destroy())

        # set position of popup from parent window
        # self._locate()

        # create widgets
        self.create_buttonbox(self.create_body(self._toplevel))

        # update the window before showing
        self._toplevel.update_idletasks()

    def show(self, position=None):
        """Create and display the popup messagebox."""
        self._result = None
        self.build()

        if position is None:
            self._locate()
        else:
            try:
                x, y = position
                self._toplevel.geometry(f'+{x}+{y}')
            except:
                self._locate()

        self._toplevel.deiconify()
        if self._alert:
            self._toplevel.bell()

        if self._initial_focus:
            self._initial_focus.focus_force()

        self._toplevel.grab_set()
        self._toplevel.place_window_center()
        def setTopmost():
            try:
                self._toplevel.attributes('-topmost', True)
            except Exception as e:
                print(f'设置窗口置顶失败: {str(e)}')
        self._toplevel.after(400, setTopmost)
        self._toplevel.wait_window()


def create(parser):
    parser.add_argument("--title", "-t", type=str, default="提示", help="消息标题")
    parser.add_argument("--type", "-y", type=str, default='info', help="消息类型")
    parser.add_argument("--content", "-m", type=str, default='', help="消息内容")
    parser.add_argument("--hideCancel", "-hc", type=lambda x: str(x) == 'True', default=False, help="是否隐藏取消按钮")
    parser.add_argument("--cancelText", "-ct", type=str, default='取消', help="取消按钮文本")
    parser.add_argument("--okText", "-ot", type=str, default='确定', help="确定按钮文本")
    params = parser.parse_args()

    enable_high_dpi_awareness()
    root = tk.Window(alpha=0.0, overrideredirect=True, maxsize=(1, 1))
    root.place_window_center()
    message = MessageBox(root)
    message.initUI(params)
    message.show()
